#include <stdlib.h>
#include "TFly_list.h"
#include "script_memory.h"

#define TFly_malloc script_malloc
#define TFly_calloc script_calloc
#define TFly_free	script_free

TFly_list_item_t *TFly_list_get_item(TFly_list_t *list)
{
	if(list == NULL){
		return NULL;
	}
	TFly_list_item_t *item = TFly_calloc(1,sizeof(TFly_list_item_t));
	item->node = list->head;
	return item;
}

void *TFly_list_item_next(TFly_list_item_t *item)
{
	if(item == NULL || item->node == NULL){
		return NULL;
	}
	void *value = item->node->value;
	item->node = item->node->next;
	return value;
}

void TFly_list_item_destroy(TFly_list_item_t *item)
{
	if(item){
		TFly_free(item);
	}
}

void *TFly_list_item_get(TFly_list_t *list,TFly_list_item_t *item)
{
	if(list == NULL || list->head == NULL || item == NULL || item->end == 1){
		return NULL;
	}

	if(item->node == NULL){
		item->list = list;
		item->node = list->head;
	}else if(item->flag){
		item->flag = 0;
	}else{
		item->prev = item->node;
		item->node = item->node->next;
	}

	if(item->node == NULL){
		item->end = 1;
		return NULL;
	}

	void *value = item->node->value;
	if(item->node->next == NULL){
		item->end = 1;
	}
	return value;
}

void TFly_list_item_delete(TFly_list_t *list, TFly_list_item_t *item)
{
	if(list == NULL || item == NULL){
		return;
	}
	if(item->node == NULL){
		return;
	}

	if(item->prev == NULL){
		list->head = item->node->next;
		script_free(item->node);
		item->node = item->node->next;
		if(item->node == NULL){
			list->end = list->head;
		}
		item->flag = 1;
	}else{
		item->prev->next = item->node->next;
		script_free(item->node);
		item->node = item->node->next;
		if(item->node == NULL){
			list->end = item->prev;
		}
		item->flag = 1;
	}
}

void *TFly_list_get_first(TFly_list_t *list)
{
	if(list->head == NULL){
		return NULL;
	}
	list->cnode = list->head;
	return list->head->value;
}

void *TFly_list_get_next(TFly_list_t *list)
{
	TFly_list_node_t *node;
	node = list->cnode;
	if(node != NULL){
		list->cnode = node->next;
		if(list->cnode){
			return list->cnode->value;
		}
	}
	return NULL;
}

void *TFly_list_get_end(TFly_list_t *list)
{
	if(list == NULL){
		return NULL;
	}

	if(list->end){
		return list->end->value;
	}
	return NULL;
}

int TFly_list_add(TFly_list_t *list, void *value)
{
	if(list == NULL){
		return -1;
	}
	TFly_list_node_t *node = TFly_calloc(1,sizeof(TFly_list_node_t));
	node->value = value;
	if(list->head == NULL){
		list->head = node;
		list->cnode = node;
	}else{
		list->end->next = node;
	}
	list->end = node;
	return 0;
}

int TFly_list_add_head(TFly_list_t *list, void *value)
{
	if(list == NULL){
		return -1;
	}
	TFly_list_node_t *node = TFly_calloc(1,sizeof(TFly_list_node_t));
	node->value = value;
	if(list->head == NULL){
		list->head = node;
		list->cnode = node;
	}else{
		node->next = list->head;
		list->head = node;
	}
	return 0;
}

int TFly_list_del(TFly_list_t *list, void *value)
{
	TFly_list_node_t *node,*pre = NULL;
	node = list->head;
	while(node != NULL){
		if(node->value == value){
			if(pre == NULL){
				list->head = list->head->next;
				list->cnode = list->head;
				if (list->end == node)
					list->end = NULL;
			}else{
				if(list->cnode == node){
					if (node->next != NULL)
						list->cnode = list->cnode->next;
					else
						list->cnode = list->head;
					
				}
				if(list->end == node){
					list->end = pre;
				}
				pre->next = node->next;
			}
			TFly_free(node);
			break;
		}
		pre = node;
		node = node->next;
	}
	return 0;
}

void *TFly_list_del_first(TFly_list_t *list)
{
	if(list == NULL || list->head == NULL){
		return NULL;
	}
	void *value = list->head->value;

	TFly_list_node_t *node = list->head;
	if(list->cnode == list->head){
		list->cnode = list->head->next;
	}
	if(list->end == list->head){
		list->end = NULL;
	}
	list->head = list->head->next;
	TFly_free(node);

	return value;
}

TFly_list_t *TFly_list_create(void)
{
	TFly_list_t *list = TFly_calloc(1,sizeof(TFly_list_t));
	if (!list)
		return NULL;

	return list;
}

int TFly_list_destroy(TFly_list_t *list)
{
	TFly_free(list);
	return 0;
}
